package com.baizhi.config;


import com.baizhi.annotation.LogAnnotation;
import com.baizhi.dao.CmfzLogDao;
import com.baizhi.entity.CmfzAdmin;
import com.baizhi.entity.CmfzLog;
import com.baizhi.utils.IPKit;
import org.apache.ibatis.binding.MapperMethod;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Configuration


//先创建一个切面类
public class AopConfig {
    @Autowired
    private CmfzLogDao cmfzLogDao;
    @After("execution(* com.baizhi.service.*.*(..))")
    public void after(){
        System.out.println("前置方法");
    }


    /**
     * 日志增强
     * 1. 获取日志数据
     * 2. 日志数据添加数据库
     */
    /**
     * 日志增强
     * 1. 获取日志数据
     * 2. 日志数据添加数据库
     */
    @After("@annotation(com.baizhi.annotation.LogAnnotation)")
    public void logAfter(JoinPoint joinPoint){
        CmfzLog cmfzLog = new CmfzLog();
        /**
         * 1.获取日志数据
         */
//        获取日期
        cmfzLog.setLogDate(new Date());

//        获取ip
        /**
         * RequestContextHolder 可以获取当前线程对应的请求
         *
         * 一般情况下 ip获取会使用工具类
         */
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = IPKit.getIpAddrByRequest(request);
        cmfzLog.setLogIp(ip);

//        获取用户名
        CmfzAdmin admin = (CmfzAdmin) request.getSession().getAttribute("admin");

        if (admin == null){
            cmfzLog.setUsername("root");
        }else {
            cmfzLog.setUsername(admin.getUsername());
        }

//        操作类型和操作内容  aop不同的方法获取到的类型和内容不同
        /**
         *  通过joinPoint可以获取切入点附近所有的信息 类 方法 属性 注解 等等
         *
         *  获取当前被切方法的日志注解
         *  1 通过连接点对象joinPoint获取 方法签名对象
         *  2 通过方法签名对象获取被切的方法
         *  3 通过方法对象获取方法上的注解
         *  4 获取注解中的值
         */
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        Method method = signature.getMethod();
//        参数为 要获取的注解的类对象
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);

        cmfzLog.setLogType(annotation.type().getKey());

        cmfzLog.setLogContent(annotation.value());

        /**
         * 2.日志数据添加数据库
         */
        cmfzLogDao.insert(cmfzLog);

    }

}
